using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;


namespace SinceTimes.NetWork
{
    public class ConnectionSocket : Connection
    {
        public override bool Connected => _SOCKETHandle != null && _SOCKETHandle.Connected;
        public ConnectionSocket(MonoBehaviour owner) : base(owner)
        {

        }
        //int Send(byte[] data)
        //{
        //    if (data == null) return 0;


        //    int _len = _SOCKETHandle.Send(data);
        //    if (_len != data.Length)
        //    {
        //        Debug.LogError($"[Peer._SOCKET.Send] Error :{_len}");
        //    }
        //    else
        //    {
        //        if (Input.GetKey(KeyCode.LeftShift))
        //            Debug.Log($"[Peer._SOCKET.Send]OK :Len={_len} ;bytes:\n{Net.BYTES_STRING(data)}");
        //    }
        //    return _len;
        //}

        //IPeerConnection IPeerConnection.SetAutorBuff(byte[] _buff)
        //{
        //    throw new NotImplementedException();
        //}



        //public bool Connected => _SOCKETHandle != null && _SOCKETHandle.Connected;
        //public string Error { get; set; }


        Socket _SOCKETHandle;
        //主线程
        Thread _Main;



        //接收缓存得大小(字节)
        const  uint BUFF_SIZE = 4096;
        // 封包:长度
        const uint SIZE_LENGTH = 4;
        //封包:消息类型
        const uint SIZE_TYPE = 2;
        //封包:消息序列号
        const uint SIZE_SERIAL = 4;
        //封包:消息头 总长度 =10个字节.
        static uint SIZE_HEAD => SIZE_LENGTH + SIZE_TYPE + SIZE_SERIAL;



        Encoding _Encoding = Encoding.UTF8;
        byte[] _Buff_Recive = new byte[BUFF_SIZE];
        byte[] _MsgDataBuf = new byte[BUFF_SIZE];
        CircularBuffer m_recvStream = new CircularBuffer((int)BUFF_SIZE * 2);




        //Socket 协议,数据报文类型
        ProtocolType Protocol = ProtocolType.Tcp;
        SocketType DataType = SocketType.Stream;
        protected override void _DoConnect()
        {
            _SOCKETHandle = new Socket(AddressFamily.InterNetwork, DataType, Protocol);
            _SOCKETHandle.SendTimeout = 200;
            IAsyncResult _Async = _SOCKETHandle.ConnectAsync(Url, Port).ContinueWith((w) =>
            {
                if (_SOCKETHandle.Connected)
                {
                    _Main = new Thread(_LOOP_MAIN_ST);

                    _Main.IsBackground = true;
                    _Main.Start();

                    Error = "";
                    OnConnectSuccess();
                }
                else if (w.Exception != null)
                {
                    Error = w.Exception.Message;
                    OnConnectSuccess();

                }
                else
                {
                    Error = "连接失败";
                    OnConnectSuccess();
                }

            });
            // 等待2秒 监听是否超时
            bool _success = _Async.AsyncWaitHandle.WaitOne(1000, false); //1秒后结束
            if (!_success)
            {
                Error = "连接超时";
                OnConnectSuccess();
            }
        }
        protected override void OnConnectSuccess()
        {
            base.OnConnectSuccess();
        }

        void _LOOP_MAIN_ST(object ob)
        {
            // Socket 主循环
            int readsize = _Buff_Recive.Length;
            uint dataLen = 0;
            while (true && string.IsNullOrEmpty(Error))
            {
                try
                {
                    SocketError err = SocketError.Success;
                    uint _len = (uint)_SOCKETHandle.Receive(_Buff_Recive, 0, readsize, SocketFlags.None, out err);
                    if (err != SocketError.Success)
                    {
                        Error = $"Receive Error: {err}";
                        break;
                    }
                    if (_len <= 0)
                    {
                        Error = $"Receive len is negative";
                        break;
                    }
                    m_recvStream.Write(_Buff_Recive, (int)_len);
                    if (_len < readsize && readsize != _Buff_Recive.Length)
                    {
                        Error = $"Receive len Error, readsize:{readsize} len: {_len}";
                        break;
                    }
                    bool bError = false;
                    while (true)
                    {
                        int recvSize = m_recvStream.GetDataSize();
                        if (recvSize <= 0)
                        {
                            break;
                        }
                        if (dataLen == 0 && recvSize >= SIZE_HEAD)
                        {
                            dataLen = m_recvStream.ReadUInt32();
                        }

                        if (Net.SHOWLOG)
                            Debug.Log($"[Peer._LOOP_MAIN_ST]:Receive++ len: {_len} recvSize: {recvSize}, dataLen: {dataLen}, readSize: {readsize}");

                        if (dataLen > recvSize)  // 说明没收全，要继续收
                        {
                            readsize = (int)dataLen - recvSize;
                            break;
                        }
                        m_recvStream.Read(ref _MsgDataBuf, (int)dataLen);

                        _OnReceive(_MsgDataBuf,0, dataLen);


                    }

                    if (bError)
                        break;
                }
                catch (Exception ex)
                {
                    Error = ex.Message;
                }
            }
            _DoClose();
        }




        protected override int _DoSend(byte[] data)
        {
            if(_SOCKETHandle != null && _SOCKETHandle.Connected)
            {
  
                var len=   _SOCKETHandle.Send(data);

                _OnSend(data);

                return len;
            }

            return 0;
        }
        protected override void _DoClose(bool callback = false)
        {
            try
            {
                if (_SOCKETHandle != null)
                {
                    if (_SOCKETHandle.Connected)
                    {
                        _SOCKETHandle.Close();
                    }
                    _SOCKETHandle.Dispose();

                }
            }
            catch (Exception ex)
            {
                if (Net.SHOWERROR) Debug.LogWarning($"[Peer._Release]:_SOCKETHandle.Dispose() =Error");
                Error = ex.Message;
            }
            finally
            {
                _SOCKETHandle = null;
            }

            try
            {
                if (_Main != null)
                {
                    if (_Main.IsAlive)
                        _Main.Abort();
                }
            }
            catch (Exception ex)
            {
                if (Net.SHOWERROR) Debug.LogWarning($"[Peer._Release]:_Main.Abort() =Error");
                Error = ex.Message;
            }
            finally
            {
                _Main = null;
            }

        }

        protected override void RuntimeCheck()
        {
            base.RuntimeCheck();

            RuntimeState.State = _SOCKETHandle != null&& _SOCKETHandle.Connected? "Connected" : "null";
        }
    }
}

